package iammry.com.utils;

import android.annotation.SuppressLint;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.os.Build;
import android.widget.Toast;

import java.io.IOException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Set;
import java.util.UUID;

import iammry.com.factory.ThreadPoolFactory;
import iammry.com.mode.AppInfos;


/**
 * 
 * @author kim
 * @time 2016��4��9������11:04:55
 * @des ���� ����ԣ�����Ĺ���
 * @version 1.0
 * 
 */
public class BlueConnectionUtils {
	private Context context;
	public BluetoothDevice bluetoothDevice;
	
	private BlueConnectionUtils(Context context) {
		this.context = context;
	}

	private static BlueConnectionUtils instance = null;

	public static BlueConnectionUtils getInstance(Context context) {
		// �Ե���ģʽ�����Ż�����ֹ���̳߳�������
		if (instance == null) {
			synchronized (AppInfos.class) {

				if (instance == null) {
					instance = new BlueConnectionUtils(context);
				}
			}
		}
		return instance;
	}

	/**
	 * �������״̬
	 * 
	 * @param bondState
	 * @param bluetoothDevice
	 */
	public boolean checkConnectStatues(int bondState,
			BluetoothDevice bluetoothDevice, BluetoothAdapter mBlueAdapter) {

		
		this.bluetoothDevice = bluetoothDevice;
		boolean makePair_boolean = true;
		switch (bondState) {
		// û�����
		case BluetoothDevice.BOND_NONE:
			// ���
			try {
				// �������
				makePair_boolean = makePair(bluetoothDevice);
			} catch (Exception e) {
				e.printStackTrace();
			}
			if (makePair_boolean) {

				try {
					// �����߳���������
					ConnectBlue connectBlue = new ConnectBlue();
					ThreadPoolFactory.getNormalPool().execute(connectBlue);
				} catch (Exception e) {
					e.printStackTrace();

				}
			} else {

				Toast.makeText(context, "���ʧ�ܣ����������", Toast.LENGTH_SHORT)
						.show();

			}
			break;
		case BluetoothDevice.BOND_BONDED:
			/* ClsUtils.setPin(device.getClass(), device, strPsw); */
			try {
				// �����߳���������
				ConnectBlue connectBlue = new ConnectBlue();
				ThreadPoolFactory.getNormalPool().execute(connectBlue);
				// connect(bluetoothDevice);
			} catch (Exception e) {
				e.printStackTrace();
				System.out.println("����ʧ��");

			}
			break;

		default:
			break;
		}
		return isConnect;
	}

	/**
	 * @param device
	 * @throws IOException
	 *             ��������
	 */
	boolean flg;
	int count = 0;
	private boolean isConnect;
	private BluetoothSocket socket;

	@SuppressLint("NewApi") public void connect(BluetoothDevice device) throws IOException {
		// Fix UUID
		String SPP_UUID = AppInfos.SPP_UUID;
		UUID uuid = UUID.fromString(SPP_UUID);
		if (device == null) {

			Toast.makeText(context, "������ɨ������", Toast.LENGTH_SHORT).show();
		}
		int sdk = Integer.parseInt(Build.VERSION.SDK);
		if (sdk >= 10) {
			
			socket = device.createInsecureRfcommSocketToServiceRecord(uuid);
		}else{
			
			socket = device.createRfcommSocketToServiceRecord(uuid);
			
			
		}

		if (socket != null) {
			if (!socket.isConnected()) {

				socket.connect();
				
				AppInfos.getInstance().socket=socket;

			}
		}
		
	}

	/**
	 * �������
	 * 
	 * @param bluetoothDevice
	 * @throws Exception
	 */
	private boolean makePair(BluetoothDevice bluetoothDevice) throws Exception {

		setPin(bluetoothDevice.getClass(), bluetoothDevice, "8888");
		Method createBondMethod = BluetoothDevice.class.getMethod("createBond");
		Boolean invoke = (Boolean) createBondMethod.invoke(bluetoothDevice);
		return invoke.booleanValue();
	}

	/**
	 * �Ƴ������������
	 */
	public void removeBlue(BluetoothDevice device) {

		try {
			Method m = device.getClass()
					.getMethod("removeBond", (Class[]) null);
			m.invoke(device, (Object[]) null);
			System.out.println("�Ƴ�������Գɹ�");
		} catch (Exception e) {
			/* Log.e(TAG, e.getMessage()); */
		}
	}

	public void removeAllBlue(BluetoothAdapter mBlueAdapter) {
		// BluetoothAdapter blueAdapter = BluetoothAdapter.getDefaultAdapter();
		Set<BluetoothDevice> devices = mBlueAdapter.getBondedDevices();
		if (devices != null) {
			for (BluetoothDevice bluetoothDevice : devices) {
				System.out.println("�����豸" + bluetoothDevice);
				// �Ƴ����гɹ���Ե�����
				removeBlue(bluetoothDevice);
			}
		}
		// return blueAdapter;
	}

	static public boolean setPin(Class<? extends BluetoothDevice> btClass,
			BluetoothDevice btDevice, String str) throws Exception {
		try {
			Method removeBondMethod = btClass.getDeclaredMethod("setPin",
					new Class[] { byte[].class });
			Boolean returnValue = (Boolean) removeBondMethod.invoke(btDevice,
					new Object[] { str.getBytes() });
			// Log.e("returnValue", "" + returnValue);
		} catch (SecurityException e) {
			// throw new RuntimeException(e.getMessage());
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// throw new RuntimeException(e.getMessage());
			e.printStackTrace();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return true;

	}

	class ConnectBlue implements Runnable {

		@Override
		public void run() {

			try {
				connect(bluetoothDevice);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				// Connection refused
			}
		}

	}

	/**
	 * get bonded devices
	 */
	public ArrayList<String> getBondedDevicesAddress(
			BluetoothAdapter mBlueAdapter) {
		ArrayList<String> arrayAddress = new ArrayList<String>();

		Set<BluetoothDevice> devices = mBlueAdapter.getBondedDevices();
		if (devices != null) {
			for (BluetoothDevice bluetoothDevice : devices) {
				System.out.println("�����豸" + bluetoothDevice.getName());

				// get blue name and address
				String name = bluetoothDevice.getName();
				String address = bluetoothDevice.getAddress();

				// match corresponding toothbrush
				if (name.equals(AppInfos.blueName) && !name.endsWith(".Ble")) {
					arrayAddress.add(address);
				}
			}
		}
		return arrayAddress;
	}

	/**
	 * get phone connecting blue device
	 * 
	 * @param mBlueAdapter
	 * @return
	 */
	public ArrayList<BluetoothDevice> getBondedDevices(
			BluetoothAdapter mBlueAdapter) {
		ArrayList<BluetoothDevice> arrayDevices = new ArrayList<BluetoothDevice>();

		Set<BluetoothDevice> devices = mBlueAdapter.getBondedDevices();
		if (devices != null) {
			for (BluetoothDevice bluetoothDevice : devices) {
				System.out.println("�����豸" + bluetoothDevice.getName());

				// get blue name 
				String name = bluetoothDevice.getName();

				// match corresponding toothbrush
				if (name.equals(AppInfos.blueName) && !name.endsWith(".Ble")) {
					arrayDevices.add(bluetoothDevice);
				}
			}
		}
		return arrayDevices;
	}

	public static boolean removeBond(Class<?> btClass, BluetoothDevice btDevice)
			throws Exception {
		Method removeBondMethod = btClass.getMethod("removeBond");
		Boolean returnValue = (Boolean) removeBondMethod.invoke(btDevice);
		return returnValue.booleanValue();
	}
}
